#ifndef __THREAD_H__
#define __THREAD_H__

/*********************************************************************
 * INCLUDES
 */

#ifdef __cplusplus
extern "C" {
#endif

/*********************************************************************
 *  EXTERNAL VARIABLES
 */

/*********************************************************************
 * MACROS
 */

// Timeout value.
#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value.

// Thread attributes (attr_bits in \ref osThreadAttr_t).
#define osThreadDetached      0x00000000U ///< Thread created in detached mode (default)
#define osThreadJoinable      0x00000001U ///< Thread created in joinable mode

/*********************************************************************
 * TYPES
 */

/// Version information.
typedef struct 
{
    uint32_t                       api;   ///< API version (major.minor.rev: mmnnnrrrr dec).
    uint32_t                    kernel;   ///< Kernel version (major.minor.rev: mmnnnrrrr dec).
} osVersion_t;
 
/// Kernel state.
typedef enum 
{
    osKernelInactive        =  0,         ///< Inactive.
    osKernelReady           =  1,         ///< Ready.
    osKernelRunning         =  2,         ///< Running.
    osKernelLocked          =  3,         ///< Locked.
    osKernelSuspended       =  4,         ///< Suspended.
    osKernelError           = -1,         ///< Error.
    osKernelReserved        = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization.
} osKernelState_t;
 
/// Thread state.
typedef enum 
{
    osThreadInactive        =  0,         ///< Inactive.
    osThreadReady           =  1,         ///< Ready.
    osThreadRunning         =  2,         ///< Running.
    osThreadBlocked         =  3,         ///< Blocked.
    osThreadTerminated      =  4,         ///< Terminated.
    osThreadError           = -1,         ///< Error.
    osThreadReserved        = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
} osThreadState_t;
 
/// Priority values.
typedef enum 
{
    osPriorityNone          =  0,         ///< No priority (not initialized).
    osPriorityIdle          =  1,         ///< Reserved for Idle thread.
    osPriorityLow           =  8,         ///< Priority: low
    osPriorityLow1          =  8+1,       ///< Priority: low + 1
    osPriorityLow2          =  8+2,       ///< Priority: low + 2
    osPriorityLow3          =  8+3,       ///< Priority: low + 3
    osPriorityLow4          =  8+4,       ///< Priority: low + 4
    osPriorityLow5          =  8+5,       ///< Priority: low + 5
    osPriorityLow6          =  8+6,       ///< Priority: low + 6
    osPriorityLow7          =  8+7,       ///< Priority: low + 7
    osPriorityBelowNormal   = 16,         ///< Priority: below normal
    osPriorityBelowNormal1  = 16+1,       ///< Priority: below normal + 1
    osPriorityBelowNormal2  = 16+2,       ///< Priority: below normal + 2
    osPriorityBelowNormal3  = 16+3,       ///< Priority: below normal + 3
    osPriorityBelowNormal4  = 16+4,       ///< Priority: below normal + 4
    osPriorityBelowNormal5  = 16+5,       ///< Priority: below normal + 5
    osPriorityBelowNormal6  = 16+6,       ///< Priority: below normal + 6
    osPriorityBelowNormal7  = 16+7,       ///< Priority: below normal + 7
    osPriorityNormal        = 24,         ///< Priority: normal
    osPriorityNormal1       = 24+1,       ///< Priority: normal + 1
    osPriorityNormal2       = 24+2,       ///< Priority: normal + 2
    osPriorityNormal3       = 24+3,       ///< Priority: normal + 3
    osPriorityNormal4       = 24+4,       ///< Priority: normal + 4
    osPriorityNormal5       = 24+5,       ///< Priority: normal + 5
    osPriorityNormal6       = 24+6,       ///< Priority: normal + 6
    osPriorityNormal7       = 24+7,       ///< Priority: normal + 7
    osPriorityAboveNormal   = 32,         ///< Priority: above normal
    osPriorityAboveNormal1  = 32+1,       ///< Priority: above normal + 1
    osPriorityAboveNormal2  = 32+2,       ///< Priority: above normal + 2
    osPriorityAboveNormal3  = 32+3,       ///< Priority: above normal + 3
    osPriorityAboveNormal4  = 32+4,       ///< Priority: above normal + 4
    osPriorityAboveNormal5  = 32+5,       ///< Priority: above normal + 5
    osPriorityAboveNormal6  = 32+6,       ///< Priority: above normal + 6
    osPriorityAboveNormal7  = 32+7,       ///< Priority: above normal + 7
    osPriorityHigh          = 40,         ///< Priority: high
    osPriorityHigh1         = 40+1,       ///< Priority: high + 1
    osPriorityHigh2         = 40+2,       ///< Priority: high + 2
    osPriorityHigh3         = 40+3,       ///< Priority: high + 3
    osPriorityHigh4         = 40+4,       ///< Priority: high + 4
    osPriorityHigh5         = 40+5,       ///< Priority: high + 5
    osPriorityHigh6         = 40+6,       ///< Priority: high + 6
    osPriorityHigh7         = 40+7,       ///< Priority: high + 7
    osPriorityRealtime      = 48,         ///< Priority: realtime
    osPriorityRealtime1     = 48+1,       ///< Priority: realtime + 1
    osPriorityRealtime2     = 48+2,       ///< Priority: realtime + 2
    osPriorityRealtime3     = 48+3,       ///< Priority: realtime + 3
    osPriorityRealtime4     = 48+4,       ///< Priority: realtime + 4
    osPriorityRealtime5     = 48+5,       ///< Priority: realtime + 5
    osPriorityRealtime6     = 48+6,       ///< Priority: realtime + 6
    osPriorityRealtime7     = 48+7,       ///< Priority: realtime + 7
    osPriorityISR           = 56,         ///< Reserved for ISR deferred thread.
    osPriorityError         = -1,         ///< System cannot determine priority or illegal priority.
    osPriorityReserved      = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
} osPriority_t;
 
/// Entry point of a thread.
typedef void (*osThreadFunc_t) (void *argument);

/// Status code values returned by CMSIS-RTOS functions.
typedef enum {
    osOK                      =  0,         ///< Operation completed successfully.
    osError                   = -1,         ///< Unspecified RTOS error: run-time error but no other error message fits.
    osErrorTimeout            = -2,         ///< Operation not completed within the timeout period.
    osErrorResource           = -3,         ///< Resource not available.
    osErrorParameter          = -4,         ///< Parameter error.
    osErrorNoMemory           = -5,         ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
    osErrorISR                = -6,         ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
    osStatusReserved          = 0x7FFFFFFF  ///< Prevents enum down-size compiler optimization.
} osStatus_t;

/// \details Thread ID identifies the thread.
typedef void *osThreadId_t;

/// \details Memory Pool ID identifies the memory pool.
typedef void *osMemoryPoolId_t;

#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif

/// Attributes structure for thread.
typedef struct 
{
    const char                   *name;   ///< name of the thread
    uint32_t                 attr_bits;   ///< attribute bits
    void                      *cb_mem;    ///< memory for control block
    uint32_t                   cb_size;   ///< size of provided memory for control block
    void                   *stack_mem;    ///< memory for stack
    uint32_t                stack_size;   ///< size of stack
    osPriority_t              priority;   ///< initial thread priority (default: osPriorityNormal)
    TZ_ModuleId_t            tz_module;   ///< TrustZone module identifier
    uint32_t                  reserved;   ///< reserved (must be 0)
} osThreadAttr_t;

/// Attributes structure for memory pool.
typedef struct {
  const char                   *name;   ///< name of the memory pool
  uint32_t                 attr_bits;   ///< attribute bits
  void                      *cb_mem;    ///< memory for control block
  uint32_t                   cb_size;   ///< size of provided memory for control block
  void                      *mp_mem;    ///< memory for data storage
  uint32_t                   mp_size;   ///< size of provided memory for data storage
} osMemoryPoolAttr_t;

/* 系统任务基本操作 */
typedef struct _os_thread_base
{
    //  ==== Kernel Management Functions ====
    osStatus_t(*pfOSKernelInitialize)(void);
    osStatus_t(*pfOSKernelGetInfo)(osVersion_t *version, char *id_buf, uint32_t id_size);
    osKernelState_t(*pfOSKernelGetState)(void);
    osStatus_t(*pfOSKernelStart)(void);
    int32_t(*pfOSKernelLock)(void);
    int32_t(*pfOSKernelUnlock)(void);
    int32_t(*pfOSKernelRestoreLock)(int32_t lock);
    uint32_t(*pfOSKernelSuspend)(void);
    void(*pfOSKernelResume)(uint32_t sleep_ticks);
    uint32_t(*pfOSKernelGetTickCount)(void);
    uint32_t(*pfOSKernelGetTickFreq)(void);
    uint32_t(*pfOSKernelGetSysTimerCount)(void);
    uint32_t(*pfOSKernelGetSysTimerFreq)(void);
    // ==== Thread Management Functions ====
    osThreadId_t(*pfOSThreadNew)(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
    const char *(*pfOSThreadGetName)(osThreadId_t thread_id);
    osThreadId_t(*pfOSThreadGetId)(void);
    osThreadState_t(*pfOSThreadGetState)(osThreadId_t thread_id);
    uint32_t(*pfOSThreadGetStackSize)(osThreadId_t thread_id);
    uint32_t(*pfOSThreadGetStackSpace)(osThreadId_t thread_id);
    osStatus_t(*pfOSThreadSetPriority)(osThreadId_t thread_id, osPriority_t priority);
    osPriority_t(*pfOSThreadGetPriority)(osThreadId_t thread_id);
    osStatus_t(*pfOSThreadYield)(void);
    osStatus_t(*pfOSThreadSuspend)(osThreadId_t thread_id);
    osStatus_t(*pfOSThreadResume)(osThreadId_t thread_id);
    osStatus_t(*pfOSThreadDetach)(osThreadId_t thread_id);
    osStatus_t(*pfOSThreadJoin)(osThreadId_t thread_id);
    void(*pfOSThreadExit)(void);
    osStatus_t(*pfOSThreadTerminate)(osThreadId_t thread_id);
    uint32_t(*pfOSThreadGetCount)(void);
    uint32_t(*pfOSThreadEnumerate)(osThreadId_t *thread_array, uint32_t array_items);
} OS_THREAD_BASE_S;

/*********************************************************************
 * FUNCTIONS
 */

/**
 *   @Description: 系统模块安装
 *   @param : NA
 *   @return: _OK/_ERR
 */
int32_t osInstall(void);

/**
 *   @Description: 系统模块卸载
 *   @param : NA
 *   @return: _OK/_ERR
 */
int32_t osUninstall(void);

//  ==== Kernel Management Functions ====
 
/// Initialize the RTOS Kernel.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelInitialize (void);
 
///  Get RTOS Kernel Information.
/// \param[out]    version       pointer to buffer for retrieving version information.
/// \param[out]    id_buf        pointer to buffer for retrieving kernel identification string.
/// \param[in]     id_size       size of buffer for kernel identification string.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size);
 
/// Get the current RTOS Kernel state.
/// \return current RTOS Kernel state.
osKernelState_t osKernelGetState (void);
 
/// Start the RTOS Kernel scheduler.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelStart (void);
 
/// Lock the RTOS Kernel scheduler.
/// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelLock (void);
 
/// Unlock the RTOS Kernel scheduler.
/// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelUnlock (void);
 
/// Restore the RTOS Kernel scheduler lock state.
/// \param[in]     lock          lock state obtained by \ref osKernelLock or \ref osKernelUnlock.
/// \return new lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelRestoreLock (int32_t lock);
 
/// Suspend the RTOS Kernel scheduler.
/// \return time in ticks, for how long the system can sleep or power-down.
uint32_t osKernelSuspend (void);
 
/// Resume the RTOS Kernel scheduler.
/// \param[in]     sleep_ticks   time in ticks for how long the system was in sleep or power-down mode.
void osKernelResume (uint32_t sleep_ticks);
 
/// Get the RTOS kernel tick count.
/// \return RTOS kernel current tick count.
uint32_t osKernelGetTickCount (void);
 
/// Get the RTOS kernel tick frequency.
/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second.
uint32_t osKernelGetTickFreq (void);
 
/// Get the RTOS kernel system timer count.
/// \return RTOS kernel current system timer count as 32-bit value.
uint32_t osKernelGetSysTimerCount (void);
 
/// Get the RTOS kernel system timer frequency.
/// \return frequency of the system timer in hertz, i.e. timer ticks per second.
uint32_t osKernelGetSysTimerFreq (void);
 
 
//  ==== Thread Management Functions ====
 
/// Create a thread and add it to Active Threads.
/// \param[in]     func          thread function.
/// \param[in]     argument      pointer that is passed to the thread function as start argument.
/// \param[in]     attr          thread attributes; NULL: default values.
/// \return thread ID for reference by other functions or NULL in case of error.
osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
 
/// Get name of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return name as null-terminated string.
const char *osThreadGetName (osThreadId_t thread_id);
 
/// Return the thread ID of the current running thread.
/// \return thread ID for reference by other functions or NULL in case of error.
osThreadId_t osThreadGetId (void);
 
/// Get current thread state of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return current thread state of the specified thread.
osThreadState_t osThreadGetState (osThreadId_t thread_id);
 
/// Get stack size of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return stack size in bytes.
uint32_t osThreadGetStackSize (osThreadId_t thread_id);
 
/// Get available stack space of a thread based on stack watermark recording during execution.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return remaining stack space in bytes.
uint32_t osThreadGetStackSpace (osThreadId_t thread_id);
 
/// Change priority of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \param[in]     priority      new priority value for the thread function.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority);
 
/// Get current priority of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return current priority value of the specified thread.
osPriority_t osThreadGetPriority (osThreadId_t thread_id);
 
/// Pass control to next thread that is in state \b READY.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadYield (void);
 
/// Suspend execution of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadSuspend (osThreadId_t thread_id);
 
/// Resume execution of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadResume (osThreadId_t thread_id);
 
/// Detach a thread (thread storage can be reclaimed when thread terminates).
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadDetach (osThreadId_t thread_id);
 
/// Wait for specified thread to terminate.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadJoin (osThreadId_t thread_id);
 
/// Terminate execution of current running thread.
void osThreadExit (void);
 
/// Terminate execution of a thread.
/// \param[in]     thread_id     thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadTerminate (osThreadId_t thread_id);
 
/// Get number of active threads.
/// \return number of active threads.
uint32_t osThreadGetCount (void);
 
/// Enumerate active threads.
/// \param[out]    thread_array  pointer to array for retrieving thread IDs.
/// \param[in]     array_items   maximum number of items in array for retrieving thread IDs.
/// \return number of enumerated threads.
uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items);

#ifdef __cplusplus
}
#endif /* end of __cplusplus */

#endif  // __THREAD_H__

/************************************** The End Of File **************************************/

